package com.ren.fm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ren.cache.annotation.MultiCache;
import com.ren.feign.api.recl_user.ReclUserClient;
import com.ren.feign.entity.ReclUserVo;
import com.ren.fm.constant.CachePrefix;
import com.ren.utils.page.PageItem;
import com.ren.fm.entity.ReclFm;
import com.ren.fm.entity.vo.ReclFmQueryVo;
import com.ren.fm.entity.vo.ReclFmVo;
import com.ren.fm.mapper.ReclFmMapper;
import com.ren.fm.service.ReclFmCollectionService;
import com.ren.fm.service.ReclFmCommentService;
import com.ren.fm.service.ReclFmPraiseService;
import com.ren.fm.service.ReclFmService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author RZY
 * @since 2022-07-13
 */
@Service
public class ReclFmServiceImpl extends ServiceImpl<ReclFmMapper, ReclFm> implements ReclFmService {

    @Autowired
    ReclFmPraiseService fmPraiseService;

    @Autowired
    ReclFmCollectionService fmCollectionService;

    @Autowired
    ReclFmCommentService fmCommentService;

    @Autowired
    ReclUserClient userClient;

    /**
     * @param id FM记录id
     * @return ReclFm对象
     */
    @Override
    public ReclFmVo getFmVoById(Long id) {
        //获取FM对象
        ReclFm reclFm = getFmById(id);
        //远程feign获取上传用户信息
        ReclUserVo userVo = userClient.getRemoteFmUserInfo(reclFm.getUploadUserId());
        ReclFmVo reclFmVo = new ReclFmVo();
        //封装ReclFmVO
        BeanUtils.copyProperties(userVo, reclFmVo);
        BeanUtils.copyProperties(reclFm, reclFmVo);
        return reclFmVo;
    }

    /**
     * 获取FM的封装对象
     *
     * @param id
     * @return
     */
    @MultiCache(cacheGroup = "recl_fm",
        prefixKey = CachePrefix.FM_ITEM_KEY_PREFIX,
        key = "#id",
        expireTime = 70,
        sync = true)
    private ReclFm getFmById(Long id) {
        return this.getById(id);
    }

    /**
     *
     * @param reclFm 需要更新reclFM
     * @return 返回更新结果
     */
    @Override
    public boolean updateFmById(ReclFm reclFm) {
        return this.updateById(reclFm);
    }

    /**
     *
     * @param id 需要删除FM对应id
     * @return 返回删除结果
     */
    @Override
    public boolean delFmById(Long id) {
        return this.removeById(id);
    }

    /**
     *
     * @param reclFm 需要添加的reclFM
     * @return 返回添加结果
     */
    @Override
    public boolean addFm(ReclFm reclFm) {
        return this.saveOrUpdate(reclFm);
    }

    /**
     * @param userId 用户id
     * @return 返回用户点赞的reclFm
     */
    @Override
    public List<ReclFmVo> getFmByPraiseUserId(Long userId) {
        List<ReclFm> reclFms = this.baseMapper.getFmByPraiseUserId(userId);
        //获取上传用户的id
        List<Long> userIds = reclFms.stream().map(ReclFm::getUploadUserId).collect(Collectors.toList());
        //openFeign远程调用并封装ReclFmVos
        return getFmVos(userIds, reclFms);
    }

    /**
     * @param userId 用户id
     * @return 返回用户评论的reclFm
     */
    @Override
    public List<ReclFmVo> getFmByCommentUserId(Long userId) {
        List<ReclFm> reclFms = this.baseMapper.getFmByCommentUserId(userId);
        //获取上传用户的id
        List<Long> userIds = reclFms.stream().map(ReclFm::getUploadUserId).collect(Collectors.toList());
        //openFeign远程调用并封装ReclFmVos
        return getFmVos(userIds, reclFms);
    }

    /**
     * @param userId 用户id
     * @return 返回用户收藏的reclFm
     */
    @Override
    public List<ReclFmVo> getFmByCollectionUserId(Long userId) {
        List<ReclFm> reclFms = this.baseMapper.getFmByCollectionUserId(userId);
        //获取上传用户的id
        List<Long> userIds = reclFms.stream().map(ReclFm::getUploadUserId).collect(Collectors.toList());
        //openFeign远程调用并封装ReclFmVos
        return getFmVos(userIds, reclFms);
    }

    /**
     *
     * @param reclFmQueryVo 筛选前台参数封装
     * @param current   查询页号
     * @param limit   每页数据量
     * @return 返回封装前台分页对象pageItem
     */
    @Override
    public PageItem<ReclFmVo> getFrontFmOfPage(ReclFmQueryVo reclFmQueryVo, long current, long limit) {
        //创建分页对象
        Page<ReclFm> fmPage = new Page<>();
        //获取筛选参数
        String fmMood = reclFmQueryVo.getFmMood();

        QueryWrapper<ReclFm> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_create");
        wrapper.eq("status", "verify");

        if(!StringUtils.isEmpty(fmMood)) wrapper.like("fm_mood", fmMood);

        //查询分页page
        this.page(fmPage, wrapper);

        List<ReclFm> records = fmPage.getRecords();

        long total = fmPage.getTotal();

        return getPageItem(records, total);
    }

    /**
     *
     * @param records 需要封装的分页记录
     * @param total 需要封装的总页数
     * @return 返回封装分页对象ReclFmVo
     */
    private PageItem<ReclFmVo> getPageItem(List<ReclFm> records, long total) {

        //封装ReclFmVo集合
        List<ReclFmVo> reclFmVos = new ArrayList<>();
        //当没有记录时，直接返回默认PageItem
        if(records.isEmpty()) return new PageItem<ReclFmVo>().setPageRecords(reclFmVos)
                .setTotal(0);

        //利用stream流获取records中的上传用户id
        List<Long> userIds = records.stream().map(ReclFm::getUploadUserId).collect(Collectors.toList());
        //远程调用feign接口批量擦查询用户信息
        List<ReclUserVo> userVos = userClient.getRemoteFmUsersInfo(userIds);

        for(int i = 0; i < records.size(); i++) {
            ReclFmVo reclFmVo = new ReclFmVo();
            BeanUtils.copyProperties(userVos.get(i), reclFmVo);
            BeanUtils.copyProperties(records.get(i), reclFmVo);
            reclFmVos.add(reclFmVo);
        }
        //封装分页对象pageItem
        return new PageItem<ReclFmVo>().setPageRecords(reclFmVos)
                .setTotal(total);
    }

    /**
     *
     * @param userIds 批量查询的用户id
     * @param reclFms 需要封装的reclFms
     * @return 返回封装集合List<ReclFmVo>
     */
    @Override
    public List<ReclFmVo> getFmVos(List<Long> userIds, List<ReclFm> reclFms) {
        //封装ReclFmVo集合
        List<ReclFmVo> reclFmVos = new ArrayList<>();
        //远程调用feign接口批量擦查询用户信息
        List<ReclUserVo> userVos = userClient.getRemoteFmUsersInfo(userIds);

        for(int i = 0; i < reclFms.size(); i++) {
            ReclFmVo reclFmVo = new ReclFmVo();
            BeanUtils.copyProperties(userVos.get(i), reclFmVo);
            BeanUtils.copyProperties(reclFms.get(i), reclFmVo);
            reclFmVos.add(reclFmVo);
        }
        return reclFmVos;
    }

    /**
     *
     * @param reclFmQueryVo 筛选参数封装
     * @param current   查询页号
     * @param limit   每页数据量
     * @return 返回封装分页对象pageItem
     */
    @Override
    public PageItem<ReclFmVo> getFmOfPage(ReclFmQueryVo reclFmQueryVo, long current, long limit) {
        //创建分页对象
        Page<ReclFm> fmPage = new Page<>();
        //获取筛选参数
        String fmTitle = reclFmQueryVo.getFmTitle();
        String fmMood = reclFmQueryVo.getFmMood();
        String start = reclFmQueryVo.getStart();
        String end = reclFmQueryVo.getEnd();
        String status = reclFmQueryVo.getStatus();

        QueryWrapper<ReclFm> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_create");

        if(!StringUtils.isEmpty(fmTitle)) wrapper.like("fm_title", fmTitle);

        if(!StringUtils.isEmpty(fmMood)) wrapper.like("fm_mood", fmMood);

        if(!StringUtils.isEmpty(start)) wrapper.ge("gmt_create", start);

        if(!StringUtils.isEmpty(end)) wrapper.le("gmt_modified", end);

        if(!StringUtils.isEmpty(status)) wrapper.eq("status", status);
        //查询分页page
        this.page(fmPage, wrapper);

        List<ReclFm> records = fmPage.getRecords();

        long total = fmPage.getTotal();

        return getPageItem(records, total);
    }

}
